// Copyright 2012 dmitry.a.novikov@gmail.com
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// CnsZ::Object declaration


#ifndef _INCLUDED_CNZ_CORE_H_
#define _INCLUDED_CNZ_CORE_H_

#include "exception.h"

namespace CnsZ {

  class FileException : public Exception {
  public:
    FileException(const String& pathName) : Exception(pathName) {}
  };

  class FileNotFound : public FileException {
  public:
    FileNotFound(const String& pathName) : FileException(pathName) {}
  };

  class FileReadOnly : public FileException {
  public:
    FileReadOnly(const String& pathName) : FileException(pathName) {}
  };

  class Module;
  class Stream;

  class System {
  public:
    virtual String findFile(const String& name);

    enum FileOptions {
      ReadAccess        = 0,
      WriteAccess       = 1,
      CreateIfNotFound  = 2|ReadAccess|WriteAccess,
    };

    virtual P<Stream> file(const String& pathName, int options = ReadAccess);

    virtual P<Module> loadModule(const String& name);
  };

  typedef Double Real;

  class Dictionary;

  class Settings {
  public:
    enum IntegerSettingId {
    };
    enum RealSettingId {
    };
    enum StringSettingId {
      AppName,
      AppRootFolder,
      AppStorageFileName,
    };
    enum ObjectSettingId {
      AppStorage,
    };

    virtual Int64 getInteger(IntegerSettingId id);

    virtual Real getReal(RealSettingId id);

    virtual String getString(StringSettingId id);

    virtual P<Object> getObject(ObjectSettingId id);
  };

  class Core : public Object {
  public:
    P<Dictionary> classes() const;

    static P<Core> initialize(System& system, Settings& settings);
  };

}

#endif //#ifndef _INCLUDED_CNZ_CORE_H_